C语言从无到有构建一个学生成绩管理系统

您所在的位置:网站首页 c语言 录入学生的学号和成绩 C语言从无到有构建一个学生成绩管理系统

C语言从无到有构建一个学生成绩管理系统

2023-03-10 10:55| 来源: 网络整理| 查看: 265

#include //标准输入输出

#include //内存分配

#include

/*####说明####

简单学生管理系统

vc++6.0编译无error,无warning

已实现功能:添加学生,列出学生信息列表,删除学生,退出,学号重复检查,排序功能,

多科成绩录入(求平均成绩,及总平均成绩),保存记录,读取记录,修改功能;

待实现功能:查询......

第一天、创建文件,开始编写,增加添加学生函数,增加列出学生函数,增加删除学生函数,退出 版本1.0

第二天、修改内容:增加学号重复检查函数,修复显示内容时程序终止,输出列表函数优化,添加学生函数优化 1.1

第三天、修改内容:增加排序函数,删除函数内部优化,main函数内部改动,添加学生函数优化 1.2

第四天、修改内容:增加多科目录入,添加函数优化,新增总成绩与平均成绩显示,排序函数优化,输出函数改动 1.3

第五天、修改内容:新增保存函数,读取函数,主程序修改,新增链表清除函数1.4

第六天、修改内容:新增修改函数,新增宏定义MAX_SCORE and MAX_SNO,方便程序的修改,修改程序中所有warning,一些bug修正1.5

*/

//常量定义区+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#define bool int //由于C语言中不存在bool型,所以这里把它定义成int型

#define true 1 //同上

#define false 0 //↑

#define LEN sizeof(struct ryb) //动态内存分配空间大小

#define DATAFILE "DATAFILE.WL"//数据保存文件名

#define MAX_SCORE 150 //最高分数上限值

#define MAX_SNO 200 //最多录入学生上限值,即能输入的最大学号数

//END常量定义============================================================================================================

//声明函数=================================================================================================================

struct ryb * del_item_ryb (struct ryb * head,int sno,int * del_message);//删除指定学号节点(链表头,欲删除学号,处理结果(1为删除成功,0为删除失败)),返回删除后的链表头

struct ryb * create_item_ryb (struct ryb * head);//向指定的链表添加学生,并返回链表头

void put_ryb (struct ryb * head);//输出学号及成绩(欲输出链表头)

bool is_sno(struct ryb * head, int sno );//判断指定学号是否存在,如存在返回true,不存在返回false(链表头,欲判断学号)

struct ryb * order(struct ryb * head, enum ordertype type, int fs );//排序函数;(链表头,排序方式(asc或desc),排序类型(1为按学号,2为按总成绩))

bool save_data(struct ryb * head);//保存链表数据函数(欲保存链表头)

struct ryb * read_data(void);//读取数据到链表,并返回链表头

void clear(struct ryb * head);//清除函数,清除指定链表所有数据,释放内存空间

void amend_ryb(struct ryb * head, int sno);//修改函数,修改指定学号学生成绩信息(链表头,要修改成绩的学生学号)

struct ryb { //定义链表数据结构

int sno; //学号

int chinese; //语文

int math; //数学

int english; //英语

int clanguage; //C语言

int tiyu; //体育

int score; //总成绩

struct ryb *next;

};

enum ordertype{//定义排序枚举类型

asc,desc

};

//性感的分割线$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$主程序$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

int main ( void )

{

struct ryb * head,* temp_h;//链表头,临时链表

bool exit = false;

short int value;//接受输入信息1,2,3,4 1表示添加信息,2显示信息,3删除信息,4排序,5退出

int sno, *del_message = 0;//学号,删除函数处理结果(1为删除成功,0为删除失败)

int pxfs,pxlx;//排序方式,排序类型(方式asc\desc);(类型 1学号,2成绩)

char is_quit;//表示是否退出,y或Y表示退出,否则不退出

char is_save;//表示是否保存数据,y或Y表示保存,否则不保存

char is_read;//表示是否读取数据,y或Y表示读取,否则不读取

bool ssave;//表示是否保存成功,true表示成功,false表示保存失败

int amend_sno; //表示要修改的学号

head = (struct ryb *) malloc(LEN);//创建初始链表

head->sno =0;//链表赋初值

head->next = NULL;

do

{

printf("学生管理系统v1.5(C语言版)\n\n");

printf("①添加学生\n②显示成绩链表\n③删除学生\n④排序\n⑤保存数据\n⑥读取数据\n⑦修改\n⑧退出系统\n\n");

printf("等待命令输入:");

fflush(stdin);//清空键盘缓冲区

scanf("%d",&value);

if(value == 1)//添加

{

head = create_item_ryb(head);//添加信息

printf("录入信息结束!\n");

system("pause");

}else if (value == 2)//显示

{

put_ryb(head); //显示信息

system("pause");

}else if(value == 3)//删除

{

printf("请输入要删除的学生学号:");

fflush(stdin);//清空键盘缓冲区

scanf("%d",&sno);

head = del_item_ryb(head,sno, del_message); //删除

if(*del_message == 1)

{

printf("删除成功!!!\n");

}

else{

printf("删除失败!!!\n");

}

system ("pause");

}else if(value == 4)//排序

{

r: printf ("请请输入排序方式(1升序,2降序):");

fflush(stdin);

scanf("%d",&pxfs);

printf ("请输入排序类型(1按学号,2按成绩):");

fflush(stdin);

scanf("%d",&pxlx);

if (pxfs >2 || pxfs 2 || pxlx 0 && amend_sno sno==sno)

{

if(p == head)//如果第一个为要删除的值

{

head = head->next;//修改链表头

//printf("已成功修改头指针sno=%d\n",head->sno);

}

else

{

p1->next = p->next;//将链表节点指向要删除的链表节点的下一节点

free(p);//释放已删除的链表节点内存

}

*message = 1;

break;

}

p1 = p;//保存当前链表节点

p = p->next;

if(p->next==NULL)

{

*message = 0;

}

}while(p->next);

return head;

}

#endif

struct ryb * create_item_ryb (struct ryb * head) //向指定的链表添加学生,并返回链表头

{

struct ryb *p1;

int i=1;//i表示学生数

int tempsno;//临时学号

int scorearr[5],n;//分数数组,循环值

printf("提示:当学号为0时则终止添加,并返回主界面\n\n");//输出提示信息

p1 = head;

while (p1->next != NULL)//寻找链表尾,找到后将p1指向链表尾以接受学生信息的添加

{

p1 = p1->next;

i++;

}

do {

p1->sno = 0;

sno: printf("请输入学生%d学号:",i);

fflush(stdin);//清空键盘缓冲区

scanf("%d",&tempsno);

if(tempsno != 0)

{

if (is_sno(head,tempsno) == false)//判断学号是否存在

{

p1->sno = tempsno;

}

else {

printf ("学号[%d]已存在!!!\n",tempsno);

goto sno;

}

}

else{

continue;

}

printf("---------------------------------------------\n");

printf("请输入学生%d成绩(语文,数学,英语,C语言,体育,以逗号分隔):",i);

for(n=0;nsno == 0)

{

;

}

else if(p1->sno < 1 || p1->sno > MAX_SNO)//判断学号是否合法,(1~200)

{

printf("学号输入不合法,学号为1-%d之间的数包括(1,%d)!!!\n",MAX_SNO,MAX_SNO);

system("pause");

continue;

}else//判断成绩合法性

{

for(n=0;nsno = tempsno;

p1->chinese = scorearr[0];

p1->math = scorearr[1];

p1->english = scorearr[2];

p1->clanguage = scorearr[3];

p1->tiyu = scorearr[4];

//求总成绩

p1->score=scorearr[0]+scorearr[1]+scorearr[2]+scorearr[3]+scorearr[4];

}

if(p1->sno != 0)

{

p1->next = (struct ryb *) malloc(LEN);//create一个新节点给p1->next

p1 = p1->next;//将新节点地址给p1

p1->next = NULL;//↑

}else{

p1->sno = 0;

}

i++;

}while (p1->sno != 0);//判断学号是否为0;为0退出添加

return head;

}

#if(1)

void put_ryb (struct ryb * head)//输出学号及成绩(欲输出链表头)

{

struct ryb *pryb = head;

struct ryb zcj;//总成绩

int student_num = 0;//学生人数

//初始化总成绩结构体

zcj.chinese = 0;

zcj.clanguage = 0;

zcj.english = 0;

zcj.math = 0;

zcj.tiyu = 0;

//初始化END

system("cls");

printf (" --------------\n");

printf ("|某班学生成绩表|\n");

printf (" --------------\n");

printf (" ---- ---- ---- ---- ----- ---- ------ --------\n");

printf ("|学号| |语文| |数学| |英语| |C语言| |体育| |总成绩| |平均成绩|\n");

printf (" ---- ---- ---- ---- ----- ---- ------ --------\n");//8,8,8,8,9,8,10,12

do{

if(pryb->sno != 0)//输出成绩

{

printf("%-8d%-8d%-8d%-8d%-9d%-8d%-10d%-12d\n",pryb->sno,pryb->chinese,pryb->math,

pryb->english,pryb->clanguage,pryb->tiyu,pryb->score, pryb->score / 5);

zcj.chinese = zcj.chinese + pryb->chinese ;//计算各科总成绩

zcj.clanguage = zcj.clanguage + pryb->clanguage ;

zcj.english = zcj.english + pryb->english ;

zcj.math = zcj.math + pryb->math ;

zcj.tiyu = zcj.tiyu + pryb->tiyu ;

student_num++;//记录总学生人数,表示链表不为空:

pryb=pryb->next;

}

}while(pryb->next);

if (student_num >= 1)//判断链表是否为空

{

printf ("\n\n[总平均成绩]:(语文:%d,数学:%d,英语:%d,C语言:%d,体育:%d)\n",zcj.chinese/student_num, zcj.math / student_num,

zcj.english / student_num, zcj.clanguage / student_num , zcj.tiyu / student_num);//输出总平均成绩

}else

{

printf ("没有可以输出列表!\n\n");

}

}

#endif

bool is_sno(struct ryb * head,int sno)//判断学号是否存在(头指针,学号),如学号存在返回true,不存在返回false

{

struct ryb * p;

p=head;

do {

if(p->sno == sno)

{

return true;

}

if (p->next != NULL)

{

p = p->next;

}

}while(p->next!=NULL);

return false;

}

//排序函数 排序使用冒泡算法

struct ryb * order(struct ryb * head, enum ordertype type, int fs )//排序函数;(链表头,排序方式(asc或desc),排序类型(1为按学号,2为按总成绩))

{

struct ryb *p,*rp,*ptemp,*rph;//要排序的链表,要返回的链表,临时排序链表,要返回的链表头

int max,min;

int pro_mess;//删除函数处理结果1,0

if (head->sno == 0)

{

return head;

}

p = head;

max = 0, min = 0;

rp = (struct ryb *) malloc(LEN);//create一个新节点给rp

rph = rp;

do{

ptemp = p;

if(fs == 1)//按学号

{

max = ptemp->sno;//赋初值

min = ptemp->sno;

}

else { //按成绩

max = ptemp->sno;

min = ptemp->score;

max = ptemp->score;

}

rp->sno = ptemp->sno ;

rp->score =ptemp->score ;

rp->tiyu = ptemp->tiyu ;

rp->english = ptemp->english ;

rp->chinese = ptemp->chinese ;

rp->math = ptemp->math ;

rp->clanguage = ptemp->clanguage ;

do{

if(type == desc)//降序

{

if(fs == 1)//按学号

{

if(ptemp->sno > max)

{

max = ptemp->sno;

rp->sno = ptemp->sno ;

rp->score =ptemp->score ;

rp->tiyu = ptemp->tiyu ;

rp->english = ptemp->english ;

rp->chinese = ptemp->chinese ;

rp->math = ptemp->math ;

rp->clanguage = ptemp->clanguage ;

}

}

else if (fs == 2)//按成绩

{

if(ptemp->score > max)

{

max = ptemp->score;

rp->sno = ptemp->sno ;

rp->score = ptemp->score ;

rp->tiyu = ptemp->tiyu ;

rp->english = ptemp->english ;

rp->chinese = ptemp->chinese ;

rp->math = ptemp->math ;

rp->clanguage = ptemp->clanguage ;

}

}

}

if(type == asc)//升序

{

if(fs == 1)//按学号

{

if(ptemp->sno < min)

{

min = ptemp->sno;

rp->sno = ptemp->sno ;

rp->score = ptemp->score ;

rp->tiyu = ptemp->tiyu ;

rp->english = ptemp->english ;

rp->chinese = ptemp->chinese ;

rp->math = ptemp->math ;

rp->clanguage = ptemp->clanguage ;

}

}

else if (fs == 2)//按成绩

{

if(ptemp->score < min)

{

min = ptemp->score;

rp->sno = ptemp->sno ;

rp->score = ptemp->score ;

rp->tiyu = ptemp->tiyu ;

rp->english = ptemp->english ;

rp->chinese = ptemp->chinese ;

rp->math = ptemp->math ;

rp->clanguage = ptemp->clanguage ;

}

}

}

ptemp= ptemp->next ;

}while(ptemp->next != NULL);

p=del_item_ryb(p,rp->sno, &pro_mess);

rp->next = (struct ryb *) malloc(LEN);//create一个新节点给rp->next

rp = rp->next ;

if(p->next == NULL)

{//添加链表尾信息 链表尾为一个指向NULL的空结构,以表示链表结束

rp->score = 0;

rp->sno = 0;

rp->next = NULL;

}

}while(p->next != NULL);

return rph;//返回排序后链表头

}

//排序函数END;------------------------------------------------------------------------------

bool save_data(struct ryb * head)//保存链表数据函数(欲保存链表头),成功返回true,失败返回false

{

FILE * fp;

struct ryb * p;

p = head;

if (head->sno == 0)//如果链表为空

{

return false;//返回false

}

fp = fopen(DATAFILE, "w+");//打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

do{

fprintf(fp,"%d,%d,%d,%d,%d,%d,%d",p->sno ,p->chinese ,p->math ,p->english ,p->clanguage ,

p->tiyu ,p->score );//保存结构体并以|分隔

p = p->next;//

if(p->sno != 0)//等于0表示链表结束

{

fputc('|',fp);//|这里表示数据分段

}else{

fputc('&',fp);//&这里表示文本结束

}

}while(p->sno != 0);

fclose(fp);//关闭文件

return true;

}

//savedata_END------

struct ryb * read_data(void)//读取数据到链表,并返回链表头,失败返回 NULL

{

FILE * fp;

struct ryb *head, *p;

int n;//接收fscanf()返回值,以判断是否读取正确

char temp_ch;//临时字符,存放&或|

head = (struct ryb *) malloc(LEN);//创建初始链表

p = head;

fp = fopen(DATAFILE, "r");//以只读方式打开文件

if(fp == NULL)//判断文件是否打开失败

{

return NULL;

}

while(1){

n = fscanf(fp,"%d,%d,%d,%d,%d,%d,%d",&p->sno ,&p->chinese ,&p->math ,&p->english ,

&p->clanguage ,&p->tiyu ,&p->score);

if(n != 7)

{

printf ("数据读取过程中出错,数据读取失败!T_T\n");

system("pause");

clear(head);

return NULL;

}

temp_ch = fgetc(fp);

if(temp_ch == '|')

{

p->next = (struct ryb *)malloc(LEN);

p = p->next ;

}

else {

p->next = (struct ryb *)malloc(LEN);

p = p->next ;

p->sno = 0;

p->next = NULL;

break;

}

}

return head;

}

//read_data.END-------------------

void clear(struct ryb * head)//清除函数,清除指定链表所有数据,释放内存空间

{

struct ryb * p;

while(1)

{

if(head->sno == 0)

{

free(head);//释放空间

break;

}

else{

p=head;

head = head->next ;

free(p);

}

}

}

//clear.END------------------------------------------------------------

void amend_ryb(struct ryb * head, int sno)//成绩修改函数,修改指定学号学生成绩信息(链表头,要修改成绩的学生学号)

{

struct ryb *p;//链表

int arr[5],retvalue,i;//临时成绩数组[语,数,英,C语言,体育],scanf返回值,i循环用

p = head;

if (is_sno(head,sno) == false)//判断要修改的学生是否存在

{

printf("您要修改的学号[%d]不存在!(?_?)\n",sno);

system("pause");

return;

}

while (1)

{

if(p->sno == sno)

{

flag: printf("当前要修的学生学号为[%d],成绩:\n[语文:%d],[数学:%d],[英语:%d],[C语言:%d],[体育:%d],[总成绩:%d]\n\n",

sno,p->chinese,p->math,p->english,p->clanguage,p->tiyu,p->score);

printf("提示:各科成绩用逗号隔开,输入-1即表示不修改该科目成绩!↖(^ω^)↗\n");

printf ("请输入新的成绩[语,数,英,C语言,体育]:");

fflush(stdin);

retvalue = scanf("%d,%d,%d,%d,%d",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4]);

if (retvalue == 5)

{

for(i=0;ichinese = arr[0];

}

if(arr[1] != -1)

{

p->math = arr[1];

}

if(arr[2] != -1)

{

p->english = arr[2];

}

if(arr[3] != -1)

{

p->clanguage = arr[3];

}

if(arr[4] != -1)

{

p->tiyu = arr[4];

}

p->score = p->chinese + p->math + p->english + p->clanguage + p->tiyu;//计算修改过的总成绩

printf ("修改完毕!^_^\n");

system ("pause");

return;

}

else{

printf ("你输入的的值有误,请重新输入!→_→\n");

system("pause");

goto flag;

}

}

}

}



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3